package org.deltaset.meta.faces;

import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import org.deltaset.faces.FacesUtils;
import org.deltaset.meta.EntityResolver;

/**
 *
 * @author dmakariev
 */
public class GenericEntityConverter implements Converter, Serializable {

    private static final String ENTITY_RESOLVER_CONVERTER_KEY = GenericEntityConverter.class.getName();
    private EntityResolver entityResolver;

    public GenericEntityConverter() {
    }

    public void setEntityResolver(EntityResolver entityResolver) {
        this.entityResolver = entityResolver;
        FacesUtils.getViewScope().put(ENTITY_RESOLVER_CONVERTER_KEY, entityResolver);
    }

    private EntityResolver getEntityResolver() {
        if (null == entityResolver) {
            //needed instead of implementing StateHolder
            entityResolver = (EntityResolver) FacesUtils.getViewScope().get(ENTITY_RESOLVER_CONVERTER_KEY);
        }
        return entityResolver;
    }

    //http://www.nuwanbando.com/2008/01/validation-error-value-is-not-valid-famous-validation-error-when-using-custom-converters-in-jsf/
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String key) {
        if (null == key) {
            return null;
        }
        try {
            final Object result = FacesUtils.getViewScope().get(key);
            return result;
        } catch (Exception e) {
        }
        return null;
    }

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Object entity) {
        if (null == entity) {
            return null;
        }

        if (entity.getClass().equals(String.class)) {
            return (String) entity;
        }
        final String key = getEntityResolver().uniqueStringId(entity);
        FacesUtils.cachedInViewScope(key, entity);
        return key;
    }
}
